<?php

namespace app\v1\controller;

use support\Request;
use support\Response;
use app\model\ScoreChargeModel;
use app\model\UserModel;
use EasyWeChat\Factory;
use Exception;
use support\Db;
use app\model\ScoreLogModel;
use support\Log;

/**
 * 云豆充值控制器
 * 
 * 处理云豆充值相关功能
 * 包括云豆余额查询、充值订单创建、微信支付、充值记录等
 */
class ScoreChargeController
{
    /**
     * 获取用户云豆余额
     * 
     * @param Request $request
     * @return Response
     */
    public function balance(Request $request): Response
    {
        try {
            $user = $request->userLogin;
            if (empty($user) || empty($user['id'])) {
                throw new Exception('用户未登录');
            }

            // 检查用户是否已绑定手机号
            if (empty($user['phone'])) {
                throw new Exception('请先绑定手机号');
            }

            return json([
                'data' => [
                    'score' => $user->score ?? 0,
                    'phone' => $user->phone
                ],
                'msg' => '获取成功',
                'code' => 1
            ]);
        } catch (Exception $e) {
            return json([
                'data' => null,
                'msg' => $e->getMessage(),
                'code' => 0
            ]);
        }
    }

    /**
     * 创建云豆充值订单
     * 
     * @param Request $request
     * @return Response
     */
    public function create(Request $request): Response
    {
        try {
            $user = $request->userLogin;
            if (empty($user) || empty($user['id'])) {
                throw new Exception('用户未登录');
            }

            // 检查用户是否已绑定手机号
            if (empty($user['phone'])) {
                throw new Exception('请先绑定手机号');
            }

            $userId = $user['id'];
            $input = $request->post();
            
            // 参数验证
            $amount = (float)($input['amount'] ?? 0);
            $customAmount = (float)($input['custom_amount'] ?? 0);
            
            // 验证充值金额
            if ($amount > 0) {
                // 使用预设金额
                $chargeAmount = $amount;
                $chargeScore = $amount;
            } elseif ($customAmount > 0) {
                // 使用自定义金额
                if ($customAmount < 10) {
                    throw new Exception('自定义充值金额不能低于10元');
                }
                if ($customAmount > 5000) {
                    throw new Exception('自定义充值金额不能超过5000元');
                }
                $chargeAmount = $customAmount;
                $chargeScore = (int)$customAmount; // 1元=1云豆
            } else {
                throw new Exception('请选择充值金额');
            }

            // 开始事务
            Db::beginTransaction();

            try {
                // 创建充值记录
                $chargeRecord = new ScoreChargeModel();
                $chargeRecord->user_id = $userId;
                $chargeRecord->score = $chargeAmount;
                $chargeRecord->status = 'unpay';
                $chargeRecord->created_at = time();
                $chargeRecord->save();

                // 生成微信支付订单
                $app = Factory::payment(config('wechat.mini_app'));
                
                $outTradeNo = 'SC' . date('YmdHis') . $chargeRecord->id;
                $result = $app->order->unify([
                    'body' => '云豆充值',
                    'out_trade_no' => $outTradeNo,
                    'total_fee' => $chargeAmount * 100, // 微信支付金额单位为分
                    'trade_type' => 'JSAPI',
                    'notify_url' => config('site.site_url') . "/v1/score-charge/notify",
                    'openid' => $user['open_id']
                ]);

                if ($result['return_code'] !== 'SUCCESS' || $result['result_code'] !== 'SUCCESS') {
                    throw new Exception('微信支付订单创建失败：' . ($result['err_code_des'] ?? $result['return_msg']));
                }

                // 更新充值记录
                $chargeRecord->out_trade_no = $outTradeNo;
                $chargeRecord->save();

                Db::commit();

                // 生成支付签名
                $paySign = $app->jssdk->bridgeConfig($result['prepay_id'], false);
                
                return json([
                    'data' => [
                        'charge_id' => $chargeRecord->id,
                        'amount' => $chargeAmount,
                        'score' => $chargeScore,
                        'prepay_id' => $result['prepay_id'],
                        'timeStamp' => $paySign['timeStamp'],
                        'nonceStr' => $paySign['nonceStr'],
                        'package' => $paySign['package'],
                        'signType' => $paySign['signType'],
                        'paySign' => $paySign['paySign']
                    ],
                    'msg' => '充值订单创建成功',
                    'code' => 1
                ]);
            } catch (Exception $e) {
                Db::rollBack();
                throw $e;
            }
        } catch (Exception $e) {
            return json([
                'data' => null,
                'msg' => $e->getMessage(),
                'code' => 0
            ]);
        }
    }

    /**
     * 微信支付回调通知
     * 
     * @param Request $request
     * @return Response
     */
    public function notify(Request $request): Response
    {
        try {
            $app = Factory::payment(config('wechat.mini_app'));
            $response = $app->handlePaidNotify(function ($message, $fail) {

                // 查询充值记录
                $outTradeNo = $message['out_trade_no'];
                $chargeRecord = ScoreChargeModel::where('out_trade_no',$outTradeNo)->first();
                
                if (!$chargeRecord) {
                    return $fail('充值记录不存在');
                }

                if ($chargeRecord->status == 'pay') {
                    return true; // 已经处理过了
                }

                // 验证支付状态
                if ($message['result_code'] !== 'SUCCESS') {
                    $chargeRecord->status = 'fail'; // 支付失败
                    $chargeRecord->save();
                    return $fail('支付失败');
                }

                // 开始事务
                Db::beginTransaction();

                try {
                    // 更新充值记录状态
                    $chargeRecord->status = 'pay'; // 已支付
                    $chargeRecord->paid_at = time();
                    $chargeRecord->transaction_id = $message['transaction_id'];
                    $chargeRecord->save();

                    // 更新用户云豆余额
                    $user = UserModel::find($chargeRecord->user_id);
                    if ($user) {
                        $user->score = ($user->score ?? 0) + $chargeRecord->score;
                        $user->save();

                        // add log
                        ScoreLogModel::add($chargeRecord->user_id,$chargeRecord->score,'credit',ScoreLogModel::IN,'charge',['item_id'=>$chargeRecord->id,'comment'=>'云豆充值']);
                    }

                    Db::commit();
                    return true;
                } catch (Exception $e) {
                    Db::rollBack();
                    return $fail('处理失败：' . $e->getMessage());
                }
            });
            Log::info('微信支付回调通知：'.$response);
            return $response;
        } catch (Exception $e) {
            return json([
                'data' => null,
                'msg' => $e->getMessage(),
                'code' => 0
            ]);
        }
    }

    /**
     * 查询充值订单状态
     * 
     * @param Request $request
     * @return Response
     */
    public function status(Request $request): Response
    {
        try {
            $user = $request->userLogin;
            if (empty($user) || empty($user['id'])) {
                throw new Exception('用户未登录');
            }

            $chargeId = $request->get('charge_id');
            if (empty($chargeId)) {
                throw new Exception('充值订单ID不能为空');
            }

            $chargeRecord = ScoreChargeModel::where('id', $chargeId)
                ->where('user_id', $user['id'])
                ->first();

            if (!$chargeRecord) {
                throw new Exception('充值订单不存在');
            }

            return json([
                'data' => [
                    'charge_id' => $chargeRecord->id,
                    'amount' => $chargeRecord->amount,
                    'score' => $chargeRecord->score,
                    'status' => $chargeRecord->status,
                    'status_text' => $this->getStatusText($chargeRecord->status),
                    'created_at' => $chargeRecord->created_at,
                    'paid_at' => $chargeRecord->paid_at
                ],
                'msg' => '查询成功',
                'code' => 1
            ]);
        } catch (Exception $e) {
            return json([
                'data' => null,
                'msg' => $e->getMessage(),
                'code' => 0
            ]);
        }
    }

    /**
     * 获取充值记录列表
     * 
     * @param Request $request
     * @return Response
     */
    public function records(Request $request): Response
    {
        try {
            $user = $request->userLogin;
            if (empty($user) || empty($user['id'])) {
                throw new Exception('用户未登录');
            }

            $page = (int)($request->get('page') ?? 1);
            $limit = (int)($request->get('limit') ?? 10);
            
            if ($page < 1) $page = 1;
            if ($limit < 1 || $limit > 50) $limit = 10;

            $offset = ($page - 1) * $limit;

            $records = ScoreChargeModel::where('user_id', $user['id'])
                ->orderBy('created_at', 'desc')
                ->offset($offset)
                ->limit($limit)
                ->get();

            $total = ScoreChargeModel::where('user_id', $user['id'])->count();

            $list = [];
            foreach ($records as $record) {
                $list[] = [
                    'id' => $record->id,
                    'amount' => $record->amount,
                    'score' => $record->score,
                    'status' => $record->status,
                    'status_text' => $this->getStatusText($record->status),
                    'created_at' => $record->created_at,
                    'paid_at' => $record->paid_at
                ];
            }

            return json([
                'data' => [
                    'list' => $list,
                    'total' => $total,
                    'page' => $page,
                    'limit' => $limit,
                    'pages' => ceil($total / $limit)
                ],
                'msg' => '获取成功',
                'code' => 1
            ]);
        } catch (Exception $e) {
            return json([
                'data' => null,
                'msg' => $e->getMessage(),
                'code' => 0
            ]);
        }
    }

    /**
     * 获取状态文本
     * 
     * @param int $status
     * @return string
     */
    private function getStatusText($status): string
    {
        switch ($status) {
            case 0:
                return '待支付';
            case 1:
                return '已支付';
            case 2:
                return '已取消';
            default:
                return '未知状态';
        }
    }
} 